import { MarketImpact, PricePrediction, Transaction, ChainType } from '@/types';
import { createModuleLogger } from '@/utils/logger';
import { PriceService } from '@/services/price/PriceService';
import { DatabaseService } from '@/services/database/DatabaseService';

const logger = createModuleLogger('market-impact');

export class MarketImpactService {
  private static instance: MarketImpactService;
  private priceService: PriceService;
  private dbService: DatabaseService;
  private impactCache = new Map<string, MarketImpact>();

  private constructor(priceService: PriceService, dbService: DatabaseService) {
    this.priceService = priceService;
    this.dbService = dbService;
  }

  public static getInstance(priceService: PriceService, dbService: DatabaseService): MarketImpactService {
    if (!MarketImpactService.instance) {
      MarketImpactService.instance = new MarketImpactService(priceService, dbService);
    }
    return MarketImpactService.instance;
  }

  /**
   * 分析交易的市场影响
   */
  public async analyzeMarketImpact(transaction: Transaction): Promise<MarketImpact> {
    try {
      const cacheKey = transaction.id;
      
      // 检查缓存
      if (this.impactCache.has(cacheKey)) {
        return this.impactCache.get(cacheKey)!;
      }

      logger.info(`开始分析市场影响: ${transaction.hash}`);

      // 分析流动性影响
      const liquidityImpact = await this.analyzeLiquidityImpact(transaction);
      
      // 分析情绪影响
      const sentimentImpact = await this.analyzeSentimentImpact(transaction);
      
      // 历史比较分析
      const historicalComparison = await this.analyzeHistoricalComparison(transaction);
      
      // 生成价格预测
      const predictions = await this.generatePricePredictions(transaction, liquidityImpact);

      const marketImpact: MarketImpact = {
        transactionId: transaction.id,
        asset: transaction.tokenSymbol || this.getChainNativeToken(transaction.chain),
        chain: transaction.chain,
        liquidityImpact,
        sentimentImpact,
        historicalComparison,
        predictions
      };

      // 缓存结果
      this.impactCache.set(cacheKey, marketImpact);
      
      logger.info(`市场影响分析完成: ${transaction.hash}`);
      return marketImpact;

    } catch (error) {
      logger.error(`市场影响分析失败 ${transaction.hash}:`, error);
      throw error;
    }
  }

  /**
   * 分析流动性影响
   */
  private async analyzeLiquidityImpact(transaction: Transaction): Promise<MarketImpact['liquidityImpact']> {
    const asset = transaction.tokenSymbol || this.getChainNativeToken(transaction.chain);
    
    // 获取当前流动性数据
    const liquidityData = await this.getCurrentLiquidity(asset, transaction.chain);
    
    // 计算即时价格影响
    const immediateImpact = this.calculatePriceImpact(transaction.valueUSD, liquidityData.totalLiquidity);
    
    // 估算恢复时间
    const expectedRecoveryTime = this.estimateRecoveryTime(immediateImpact, liquidityData.tradingVolume);
    
    // 识别受影响的流动性池
    const affectedPools = await this.identifyAffectedPools(asset, transaction.chain);

    return {
      immediateImpact,
      expectedRecoveryTime,
      affectedPools
    };
  }

  /**
   * 分析情绪影响
   */
  private async analyzeSentimentImpact(transaction: Transaction): Promise<MarketImpact['sentimentImpact']> {
    // 这里应该集成社交媒体API
    // 简化实现
    const socialMentions = this.estimateSocialMentions(transaction.valueUSD);
    const sentimentScore = this.calculateSentimentScore(transaction);
    const trendingStatus = transaction.valueUSD > 10000000; // 超过1000万美元可能上热搜

    return {
      socialMentions,
      sentimentScore,
      trendingStatus
    };
  }

  /**
   * 历史比较分析
   */
  private async analyzeHistoricalComparison(transaction: Transaction): Promise<MarketImpact['historicalComparison']> {
    // 查找类似规模的历史交易
    const similarTransactions = await this.findSimilarHistoricalTransactions(transaction);
    
    if (similarTransactions.length === 0) {
      return {
        similarTransactions: 0,
        avgMarketReaction: 0,
        recoveryPattern: 'unknown'
      };
    }

    // 计算平均市场反应
    const avgMarketReaction = this.calculateAverageMarketReaction(similarTransactions);
    
    // 分析恢复模式
    const recoveryPattern = this.analyzeRecoveryPattern(similarTransactions);

    return {
      similarTransactions: similarTransactions.length,
      avgMarketReaction,
      recoveryPattern
    };
  }

  /**
   * 生成价格预测
   */
  private async generatePricePredictions(
    transaction: Transaction, 
    liquidityImpact: MarketImpact['liquidityImpact']
  ): Promise<PricePrediction[]> {
    const predictions: PricePrediction[] = [];
    const timeframes: Array<'1h' | '4h' | '24h' | '7d'> = ['1h', '4h', '24h', '7d'];

    for (const timeframe of timeframes) {
      const prediction = await this.generateTimeframePrediction(transaction, liquidityImpact, timeframe);
      predictions.push(prediction);
    }

    return predictions;
  }

  /**
   * 生成特定时间框架的预测
   */
  private async generateTimeframePrediction(
    transaction: Transaction,
    liquidityImpact: MarketImpact['liquidityImpact'],
    timeframe: '1h' | '4h' | '24h' | '7d'
  ): Promise<PricePrediction> {
    const baseImpact = liquidityImpact.immediateImpact;
    let expectedChange = 0;
    let confidence = 0;
    const factors: string[] = [];
    const riskFactors: string[] = [];

    switch (timeframe) {
      case '1h':
        expectedChange = baseImpact * 0.8; // 短期影响较强
        confidence = 0.7;
        factors.push('流动性冲击', '即时市场反应');
        if (Math.abs(baseImpact) > 0.05) {
          riskFactors.push('高波动性风险');
        }
        break;

      case '4h':
        expectedChange = baseImpact * 0.5; // 影响开始减弱
        confidence = 0.6;
        factors.push('套利活动', '流动性恢复');
        break;

      case '24h':
        expectedChange = baseImpact * 0.2; // 长期影响较小
        confidence = 0.4;
        factors.push('市场情绪', '基本面因素');
        riskFactors.push('新闻事件风险', '监管风险');
        break;

      case '7d':
        expectedChange = baseImpact * 0.1; // 几乎无影响
        confidence = 0.3;
        factors.push('基本面趋势', '宏观环境');
        riskFactors.push('市场趋势变化', '监管政策');
        break;
    }

    // 根据交易规模调整
    if (transaction.valueUSD > 50000000) { // 超过5000万美元
      expectedChange *= 1.5;
      confidence += 0.1;
      factors.push('大额交易影响');
    }

    return {
      timeframe,
      expectedChange: Math.round(expectedChange * 10000) / 100, // 转换为百分比
      confidence: Math.min(confidence, 1),
      factors,
      riskFactors
    };
  }

  /**
   * 获取当前流动性数据
   */
  private async getCurrentLiquidity(asset: string, chain: ChainType): Promise<{
    totalLiquidity: number;
    tradingVolume: number;
  }> {
    // 这里应该调用DeFi协议的API获取实际流动性数据
    // 简化实现
    const baseValues = {
      ethereum: { liquidity: 1000000000, volume: 100000000 }, // 10亿流动性，1亿交易量
      bsc: { liquidity: 500000000, volume: 50000000 },
      bitcoin: { liquidity: 2000000000, volume: 200000000 }
    };

    const base = baseValues[chain as keyof typeof baseValues] || baseValues.ethereum;
    
    return {
      totalLiquidity: base.liquidity,
      tradingVolume: base.volume
    };
  }

  /**
   * 计算价格影响
   */
  private calculatePriceImpact(transactionValue: number, totalLiquidity: number): number {
    // 使用平方根模型计算价格影响
    const impactFactor = transactionValue / totalLiquidity;
    return Math.sqrt(impactFactor) * 0.1; // 最大影响10%
  }

  /**
   * 估算恢复时间
   */
  private estimateRecoveryTime(priceImpact: number, dailyVolume: number): number {
    // 恢复时间与影响大小和流动性成反比
    const baseRecoveryTime = Math.abs(priceImpact) * 1000; // 基础恢复时间（分钟）
    const liquidityFactor = Math.max(0.1, dailyVolume / 100000000); // 流动性因子
    
    return Math.min(baseRecoveryTime / liquidityFactor, 1440); // 最大24小时
  }

  /**
   * 识别受影响的流动性池
   */
  private async identifyAffectedPools(asset: string, chain: ChainType): Promise<string[]> {
    // 这里应该查询实际的DeFi协议数据
    // 简化实现
    const commonPools = {
      ETH: ['Uniswap V3 ETH/USDC', 'Curve ETH/stETH', 'Balancer ETH/WBTC'],
      BTC: ['Uniswap V3 WBTC/ETH', 'Curve WBTC/tBTC'],
      BNB: ['PancakeSwap BNB/BUSD', 'Venus BNB Pool']
    };

    return commonPools[asset as keyof typeof commonPools] || ['Unknown Pool'];
  }

  /**
   * 估算社交媒体提及数
   */
  private estimateSocialMentions(transactionValue: number): number {
    // 基于交易金额估算社交媒体关注度
    if (transactionValue > 100000000) return Math.floor(Math.random() * 1000) + 500;
    if (transactionValue > 10000000) return Math.floor(Math.random() * 500) + 100;
    if (transactionValue > 1000000) return Math.floor(Math.random() * 100) + 10;
    return Math.floor(Math.random() * 10);
  }

  /**
   * 计算情绪分数
   */
  private calculateSentimentScore(transaction: Transaction): number {
    // 简化的情绪分析
    // 大额提现通常是负面的，大额存入可能是正面的
    let score = 0;

    // 基于交易方向
    if (transaction.toLabel?.type === 'exchange') {
      score -= 0.3; // 向交易所转账，可能卖出
    } else if (transaction.fromLabel?.type === 'exchange') {
      score += 0.2; // 从交易所转出，可能建仓
    }

    // 基于金额大小
    if (transaction.valueUSD > 50000000) {
      score -= 0.2; // 超大额可能引起恐慌
    }

    // 添加随机波动
    score += (Math.random() - 0.5) * 0.3;

    return Math.max(-1, Math.min(1, score));
  }

  /**
   * 查找相似历史交易
   */
  private async findSimilarHistoricalTransactions(transaction: Transaction): Promise<any[]> {
    // 这里应该查询数据库中的历史交易
    // 简化实现
    return [];
  }

  /**
   * 计算平均市场反应
   */
  private calculateAverageMarketReaction(transactions: any[]): number {
    if (transactions.length === 0) return 0;
    
    // 这里应该基于历史数据计算实际的市场反应
    return Math.random() * 0.1 - 0.05; // -5% 到 +5%
  }

  /**
   * 分析恢复模式
   */
  private analyzeRecoveryPattern(transactions: any[]): string {
    // 分析历史恢复模式
    const patterns = ['快速恢复', '缓慢恢复', '持续影响', '过度反应后回调'];
    return patterns[Math.floor(Math.random() * patterns.length)];
  }

  /**
   * 获取链的原生代币
   */
  private getChainNativeToken(chain: ChainType): string {
    const tokens = {
      ethereum: 'ETH',
      bsc: 'BNB',
      bitcoin: 'BTC',
      polygon: 'MATIC',
      base: 'ETH',
      solana: 'SOL'
    };

    return tokens[chain] || 'UNKNOWN';
  }

  /**
   * 获取实时市场数据
   */
  public async getRealTimeMarketData(asset: string): Promise<{
    price: number;
    change24h: number;
    volume24h: number;
    marketCap: number;
  }> {
    // 这里应该调用实际的市场数据API
    return {
      price: Math.random() * 50000,
      change24h: (Math.random() - 0.5) * 0.2,
      volume24h: Math.random() * 1000000000,
      marketCap: Math.random() * 100000000000
    };
  }

  /**
   * 清理缓存
   */
  public clearCache(): void {
    this.impactCache.clear();
    logger.debug('已清理市场影响分析缓存');
  }
} 